/**
 * 
 */
package com.nari.baseinfo.service;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;

import com.nari.baseinfo.dao.IBuildingDao;
import com.nari.baseinfo.dao.ICityDao;
import com.nari.baseinfo.dao.ICommunityDao;
import com.nari.baseinfo.dao.IFileMappingDao;
import com.nari.baseinfo.dao.IHeatMeterDao;
import com.nari.baseinfo.dao.IProjectDao;
import com.nari.baseinfo.model.ICommunity;
import com.nari.baseinfo.model.IFileMapping;
import com.nari.baseinfo.model.IHeatMeter;
import com.nari.coreframe.service.GenericServiceImpl;
import com.nari.platform.date.CalendarUtils;
import com.nari.platform.model.PageCond;
import com.nari.platform.model.ResponseMsg;
import com.nari.platform.model.ResultWithPageCond;

/**
 * 
 * @author Xiaopeng
 * @date 2013-8-1
 */
public class HeatMeterServiceImpl extends GenericServiceImpl<IHeatMeter, String> implements
		IHeatMeterService {
	private String diskFilePath;
	private String meterPicAttachFolder;
	private ICityDao iCityDao;
	private ICommunityDao iCommunityDao;
	private IBuildingDao iBuildingDao;
	private IFileMappingDao iFileMappingDao;
	private IProjectDao iProjectDao;

	/**
	 * 分页查询热量表数据
	 * @param projectUID 所属项目(可选)
	 * @param communityUID 所属小区(可选)
	 * @param meterNo 热量表表号(可选)
	 * @param meterType 热表型号(可选)
	 * @param pageCond
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-26
	 */
	public ResultWithPageCond<IHeatMeter> queryHeatMeterPage(String projectUID, String communityUID, 
			String meterNo, String meterType, PageCond pageCond) throws Exception {
		IHeatMeterDao iHeatMeterDao = (IHeatMeterDao) this.getiGenericDao();
		return iHeatMeterDao.queryHeatMeterPage(projectUID, communityUID, meterNo, meterType, pageCond);
	}
	
	/**
	 * 通过热量表列表查询与之关联的行政机构ID-机构名称映射表
	 * @param projectList 热量表列表，若列表为空，则返回空的映射表
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-6
	 */
	public Map<String, String> queryReferCitysByMeterList(List<IHeatMeter> meterList) throws Exception {
		List<String> cityIDList = null;
		if(meterList!=null && meterList.size()>0) {
			cityIDList = new ArrayList<String>();
			for(IHeatMeter heatMeter: meterList) {
				cityIDList.add(heatMeter.getProvinceCityID());
				cityIDList.add(heatMeter.getCapitalCityID());
				cityIDList.add(heatMeter.getDistrictCityID());
			}
		}
		return iCityDao.queryIdNameMapByIDList(cityIDList);
	}
	
	/**
	 * 通过热量表列表查询与之关联的项目ID-项目名称映射表
	 * @param projectList 热量表列表，若列表为空，则返回空的映射表
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-6
	 */
	public Map<String, String> queryReferProjectsByMeterList(List<IHeatMeter> meterList) throws Exception {
		List<String> projectIDList = null;
		if(meterList!=null && meterList.size()>0) {
			projectIDList = new ArrayList<String>();
			for(IHeatMeter heatMeter: meterList) {
				projectIDList.add(heatMeter.getProjectID());
			}
		}
		return this.iProjectDao.queryProjectMapByIDList(projectIDList);
	}
	
	/**
	 * 通过热量表列表查询与之关联的小区ID-小区名称映射表
	 * @param projectList 热量表列表，若列表为空，则返回空的映射表
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-6
	 */
	public Map<String, String> queryReferCommunitysByMeterList(List<IHeatMeter> meterList) throws Exception {
		List<String> communityIDList = null;
		if(meterList!=null && meterList.size()>0) {
			communityIDList = new ArrayList<String>();
			for(IHeatMeter heatMeter: meterList) {
				communityIDList.add(heatMeter.getCommunityID());
			}
		}
		return iCommunityDao.queryIdNameMapByIDList(communityIDList);
	}
	
	/**
	 * 通过热量表列表查询与之关联的楼栋ID-楼栋名称映射表
	 * @param projectList 热量表列表，若列表为空，则返回空的映射表
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-6
	 */
	public Map<String, String> queryReferBuildingsByMeterList(List<IHeatMeter> meterList) throws Exception {
		List<String> buildingIDList = null;
		if(meterList!=null && meterList.size()>0) {
			buildingIDList = new ArrayList<String>();
			for(IHeatMeter heatMeter: meterList) {
				buildingIDList.add(heatMeter.getBuildingID());
			}
		}
		return iBuildingDao.queryIdNameMapByIDList(buildingIDList);
	}
	
	/**
	 * 带附件上传的热量表信息保存及修改
	 * @param heatMeter 热量表信息实体
	 * @param attachFile 安装图片附件
	 * @param fileName 附件文件名
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-11
	 */
	public ResponseMsg saveOrUpdateHeatMeter(IHeatMeter heatMeter, File attachFile, 
			String fileName) throws Exception {
		//校验热表表号是否重复
		int uniqueCounter = this.queryMeterNoUniqueCount(heatMeter.getMeterNo(), heatMeter.getId());
		if(uniqueCounter > 0) {
			return ResponseMsg.getInstance(false, "重复的热量表表号<"+heatMeter.getMeterNo()+">，信息保存失败！");
		}
		String deleteFileMapUID = null; //修改热量表附件时，则删除原附件
		//带附件上传的热量表信息提交
		if(attachFile != null) {
			File svFile = null; //存储磁盘附件
			try {
				//附件存储路径对应的磁盘目录检测
				File fileSaveFolder = new File(this.diskFilePath+"/"+this.meterPicAttachFolder);
				if(!fileSaveFolder.exists()) fileSaveFolder.mkdirs();
				//文件名称
				String orFilename = fileName.substring(0, fileName.lastIndexOf("."));
				//文件类型
				String fileType = fileName.substring(fileName.lastIndexOf(".")+1);
				//电子文件实体映射
				IFileMapping fileMapping = new IFileMapping();
				fileMapping.setOrFilename(orFilename);
				fileMapping.setDiskID(diskFilePath);
				fileMapping.setFileType(fileType);
				fileMapping.setFileSize(attachFile.length());
				fileMapping.setCreateTime(new Date());
				//读取文件映射的唯一标识
				String fileMappingUID = this.iFileMappingDao.saveEntity(fileMapping);
				//文件存储的随机文件名
				String svFilename = fileMappingUID + "-" + CalendarUtils.parseDateToString(new Date(), "yyyy-MM-dd-HH-mm-ss");
				fileMapping.setSvFilename(svFilename);
				//文件的存储路径(相对路径)
				String savePath = this.meterPicAttachFolder + "/" + svFilename + "." + fileType;
				fileMapping.setSavePath(savePath);
				this.iFileMappingDao.updateEntity(fileMapping, fileMappingUID);
				//设置热量表附件引用信息
				deleteFileMapUID = heatMeter.getInstallPic();
				heatMeter.setInstallPic(fileMappingUID);
				//将附件文件保存到磁盘中
				svFile = new File(this.diskFilePath + "/" + savePath);
				this.iFileMappingDao.saveUpload(attachFile, svFile);
			} catch (Exception e) {
				e.printStackTrace();
				if(svFile.exists()) svFile.delete();
				throw new Exception(e.getMessage());
			}
		}
		//所属小区信息
		ICommunity community = this.iCommunityDao.queryEntityById(heatMeter.getCommunityID());
		//设置热量表所属城市
		heatMeter.setProvinceCityID(community.getProvinceCityID());
		heatMeter.setCapitalCityID(community.getCapitalCityID());
		heatMeter.setDistrictCityID(community.getDistrictCityID());
		//保存热量表信息
		if(heatMeter.getId()!=null && !"".equals(heatMeter.getId())) {
			this.getiGenericDao().updateEntity(heatMeter, heatMeter.getId());
			//删除热量表原附件
			if(deleteFileMapUID!=null && !"".equals(deleteFileMapUID)) {
				this.iFileMappingDao.deleteFileMapByUID(deleteFileMapUID);
			}
		} else {
			this.getiGenericDao().saveEntity(heatMeter);
		}
		return ResponseMsg.getInstance(true, "");
	}
	
	/**
	 * 删除热量表附件
	 * @param heatMeterUID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-11
	 */
	public ResponseMsg deleteMeterPicAttachFile(String heatMeterUID) throws Exception {
		IHeatMeter heatMeter = this.getiGenericDao().queryEntityById(heatMeterUID);
		//删除文件附件
		this.iFileMappingDao.deleteFileMapByUID(heatMeter.getInstallPic());
		//更新热量表信息
		heatMeter.setInstallPic(null);
		this.getiGenericDao().updateEntity(heatMeter, heatMeterUID);
		return ResponseMsg.getInstance(true, "");
	}
	
	/**
	 * 通过热量表唯一标识删除热量表信息，并批次删除对应的热量表附件等
	 * @param heatMeterUID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-12
	 */
	public ResponseMsg deleteHeatMeterByUID(String heatMeterUID) throws Exception {
		IHeatMeter heatMeter = this.getiGenericDao().queryEntityById(heatMeterUID);
		//删除热量表附件
		if(heatMeter.getInstallPic()!=null && !"".equals(heatMeter.getInstallPic())) {
			this.iFileMappingDao.deleteFileMapByUID(heatMeter.getInstallPic());
		}
		//删除热量表信息
		this.getiGenericDao().deleteEntityById(heatMeterUID);
		return ResponseMsg.getInstance(true, "");
	}
	
	/**
	 * 通过热量表表号查询热量表信息
	 * @param meterNo
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-30
	 */
	public IHeatMeter queryMeterByMeterNo(String meterNo) throws Exception {
		IHeatMeterDao iHeatMeterDao = (IHeatMeterDao) this.getiGenericDao();
		return iHeatMeterDao.queryMeterByMeterNo(meterNo);
	}
	
	/**
	 * 通过热量表所属关系查询热量表列表
	 * @param projectUID 所属项目(可选)
	 * @param communityUID 所属小区(可选)
	 * @param buildingUID 所属楼栋(可选)
	 * @param shareAreaUID 所属分摊域(可选)
	 * @return 若所属关系均不存在，则返回空列表
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-30
	 */
	public List<IHeatMeter> queryMetersByBelongs(String projectUID, String communityUID, 
			String buildingUID, String shareAreaUID) throws Exception {
		IHeatMeterDao iHeatMeterDao = (IHeatMeterDao) this.getiGenericDao();
		return iHeatMeterDao.queryMetersByBelongs(projectUID, communityUID, buildingUID, shareAreaUID);
	}

	/**
	 * 通过热量表所属关系统计热量表个数
	 * @param projectUID 所属项目(可选)
	 * @param communityUID 所属小区(可选)
	 * @param buildingUID 所属楼栋(可选)
	 * @param shareAreaUID 所属分摊域(可选)
	 * @return 
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-30
	 */
	public long countMeterNumberByBelongs(String projectUID, String communityUID, 
			String buildingUID, String shareAreaUID) throws Exception {
		IHeatMeterDao iHeatMeterDao = (IHeatMeterDao) this.getiGenericDao();
		return iHeatMeterDao.countMeterNumberByBelongs(projectUID, communityUID, buildingUID, shareAreaUID);
	}
	
	/**
	 * 根据所属分摊域信息查询热量表信息
	 * @param shareAreaUID 所属分摊域(必选)
	 * 说明：若分摊域ID不存在，则返回零结果集
	 * @param projectUID 所属项目(可选)
	 * @param communityUID 所属小区(可选)
	 * @param meterNo 热量表表号(可选)
	 * @param pageCond
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-9-3
	 */
	public ResultWithPageCond<IHeatMeter> queryHeatMeterPageByAreaUID(String shareAreaUID, 
			String projectUID, String communityUID, String meterNo, 
			PageCond pageCond) throws Exception {
		IHeatMeterDao iHeatMeterDao = (IHeatMeterDao) this.getiGenericDao();
		return iHeatMeterDao.queryHeatMeterPageByAreaUID(shareAreaUID, projectUID, communityUID, meterNo, pageCond);
	}
	
	/**
	 * 查询不隶属于某个分摊域下的热量表列表
	 * @param shareAreaUID 所属分摊域(必选)
	 * 说明：若分摊域ID不存在，则返回零结果集
	 * @param projectUID 所属项目(可选)
	 * @param communityUID 所属小区(可选)
	 * @param meterNo 热量表表号(可选)
	 * @param pageCond
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-9-3
	 */
	public ResultWithPageCond<IHeatMeter> queryMeterPageExceptAreaUID(String shareAreaUID, 
			String projectUID, String communityUID, String meterNo, 
			PageCond pageCond) throws Exception {
		IHeatMeterDao iHeatMeterDao = (IHeatMeterDao) this.getiGenericDao();
		return iHeatMeterDao.queryMeterPageExceptAreaUID(shareAreaUID, projectUID, communityUID, meterNo, pageCond);
	}
	
	/**
	 * 批量设置热量表所属分摊域信息
	 * @param shareAreaUID 所属分摊域
	 * @param meterIDList 热量表ID列表，格式：XXX,XXX,XXX
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-9-3
	 */
	public ResponseMsg saveHeatMeterArea(String shareAreaUID, String meterIDList) throws Exception {
		IHeatMeterDao iHeatMeterDao = (IHeatMeterDao) this.getiGenericDao();
		return iHeatMeterDao.saveHeatMeterArea(shareAreaUID, meterIDList);
	}
	
	/**
	 * 批量设置热量表所属分摊域信息
	 * @param shareAreaUID 所属分摊域
	 * @param meterOptions 热量表选项及其设置信息
	 * 	格式(热量表ID:热量表加减关系)：XXX:XXX,XXX:XXX,XXX:XXX
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-9-3
	 */
	public ResponseMsg saveHeatMeterAreaConfig(String shareAreaUID, String meterOptions) throws Exception {
		if(meterOptions!=null && !"".equals(meterOptions)) {
			String[] meterOptionArray = meterOptions.split("[,]");
			for(String meterOption: meterOptionArray) {
				String[] meterInfo = meterOption.split("[:]");
				IHeatMeter heatMeter = this.getiGenericDao().queryEntityById(meterInfo[0]);
				//设置热量表所属分摊域
				heatMeter.setShareAreaID(shareAreaUID);
				//设置热量表计算关系
				heatMeter.setCalculateType(meterInfo[1]);
				this.getiGenericDao().updateEntity(heatMeter, meterInfo[0]);
			}
			return ResponseMsg.getInstance(true, "");
		}
		return ResponseMsg.getInstance(false, "请填写完整的的分摊域、热量表配置关系");
	}
	
	/**
	 * 根据分摊域、热量表计算关系等查询热量表列表
	 * @param shareAreaUID 所属分摊域(必选)
	 * @param calculateType 热量表计算关系(必选)
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-10-4
	 */
	public List<IHeatMeter> queryHeatMetersByAreaUID(String shareAreaUID, 
			String calculateType) throws Exception {
		IHeatMeterDao iHeatMeterDao = (IHeatMeterDao) this.getiGenericDao();
		return iHeatMeterDao.queryHeatMetersByAreaUID(shareAreaUID, calculateType);
	}
	
	/**
	 * 通过热量表所属关系统计热量表的个数
	 * @param projectUID 所属项目(可选)
	 * @param communityUID 所属小区(可选)
	 * @param buildingUID 所属楼栋(可选)
	 * @param shareAreaUID 所属分摊域(可选)
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-10-23
	 */
	public int countMeterSumByBelongs(String projectUID, String communityUID, 
			String buildingUID, String shareAreaUID) throws Exception {
		IHeatMeterDao iHeatMeterDao = (IHeatMeterDao) this.getiGenericDao();
		return iHeatMeterDao.countMeterSumByBelongs(projectUID, communityUID, buildingUID, shareAreaUID);
	}
	
	/**
	 * 系统热量表表号唯一性统计
	 * @param meterNo
	 * @param meterUID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-5-8
	 */
	public int queryMeterNoUniqueCount(String meterNo, String meterUID) throws Exception {
		IHeatMeterDao iHeatMeterDao = (IHeatMeterDao) this.getiGenericDao();
		return iHeatMeterDao.queryMeterNoUniqueCount(meterNo, meterUID);
	}
	
	@Override
	public void saveHeatMeter(Collection heatmeters) throws Exception {
		IHeatMeterDao iHeatMeterDao = (IHeatMeterDao) this.getiGenericDao();
		Iterator iterator = heatmeters.iterator();
		while(iterator.hasNext()) {
			IHeatMeter heatMeter = (IHeatMeter) iterator.next();
			String meterNo = heatMeter.getMeterNo();
			IHeatMeter oldMeter = iHeatMeterDao.queryMeterByMeterNo(meterNo);
			if(oldMeter==null) {
				iHeatMeterDao.saveEntity(heatMeter);
			}else {
				heatMeter.setId(oldMeter.getId());
				BeanUtils.copyProperties(oldMeter, heatMeter);
				iHeatMeterDao.saveOrUpdateEntity(oldMeter);
			}
		}
	}
	/**
	 * @return the diskFilePath
	 */
	public String getDiskFilePath() {
		return diskFilePath;
	}

	/**
	 * @param diskFilePath the diskFilePath to set
	 */
	public void setDiskFilePath(String diskFilePath) {
		this.diskFilePath = diskFilePath;
	}

	/**
	 * @return the meterPicAttachFolder
	 */
	public String getMeterPicAttachFolder() {
		return meterPicAttachFolder;
	}

	/**
	 * @param meterPicAttachFolder the meterPicAttachFolder to set
	 */
	public void setMeterPicAttachFolder(String meterPicAttachFolder) {
		this.meterPicAttachFolder = meterPicAttachFolder;
	}

	/**
	 * @return the iCityDao
	 */
	public ICityDao getiCityDao() {
		return iCityDao;
	}

	/**
	 * @param iCityDao the iCityDao to set
	 */
	public void setiCityDao(ICityDao iCityDao) {
		this.iCityDao = iCityDao;
	}

	/**
	 * @return the iCommunityDao
	 */
	public ICommunityDao getiCommunityDao() {
		return iCommunityDao;
	}

	/**
	 * @param iCommunityDao the iCommunityDao to set
	 */
	public void setiCommunityDao(ICommunityDao iCommunityDao) {
		this.iCommunityDao = iCommunityDao;
	}

	/**
	 * @return the iBuildingDao
	 */
	public IBuildingDao getiBuildingDao() {
		return iBuildingDao;
	}

	/**
	 * @param iBuildingDao the iBuildingDao to set
	 */
	public void setiBuildingDao(IBuildingDao iBuildingDao) {
		this.iBuildingDao = iBuildingDao;
	}

	/**
	 * @return the iFileMappingDao
	 */
	public IFileMappingDao getiFileMappingDao() {
		return iFileMappingDao;
	}

	/**
	 * @param iFileMappingDao the iFileMappingDao to set
	 */
	public void setiFileMappingDao(IFileMappingDao iFileMappingDao) {
		this.iFileMappingDao = iFileMappingDao;
	}

	/**
	 * @return the iProjectDao
	 */
	public IProjectDao getiProjectDao() {
		return iProjectDao;
	}

	/**
	 * @param iProjectDao the iProjectDao to set
	 */
	public void setiProjectDao(IProjectDao iProjectDao) {
		this.iProjectDao = iProjectDao;
	}

	@Override
	public ResultWithPageCond<IHeatMeter> queryHeatMeterPage(String projectUID,
			String communityUID, String buildingUID, String unitUID,
			String meterNo, String meterType, PageCond pageCond)
			throws Exception {
		IHeatMeterDao iHeatMeterDao = (IHeatMeterDao) this.getiGenericDao();
		return iHeatMeterDao.queryHeatMeterPage(projectUID, communityUID, buildingUID, unitUID, meterNo, meterType, pageCond);
	}
	
}
